home *** CD-ROM | disk | FTP | other *** search
- /*
- * Help.m, a help object to manage and display RTF help files.
- * The help object owns its own nib section "Help.nib" which has a
- * Help panel - with an NXBrowser to display the help topics, and
- * a scrolling text view to display the help files. The help files are
- * all stored as RTF text files in a directory called Help within the
- * app wrapper. At init time, the Help object loads the browser with
- * names of all the files found in the Help directory. When a name is
- * chosen from the browser, the help object opens a stream on that file
- * and read the rich text into the text object. The help object also
- * responds to request for context-sensitive help, by trying to find an
- * appropriate help file for the view that was moused down in.
- * This object is a useful addition to any program, because all users
- * appreciate help!
- *
- * Author: Julie Zelenski, NeXT Developer Support
- * You may freely copy, distribute and reuse the code in this example.
- * NeXT disclaims any warranty of any kind, expressed or implied, as to
- * its fitness for any particular use.
- */
-
- /* Modified starting 9/21/91 by Subrata K. Sircar */
- /* Mostly I've removed functionality. */
-
- #import "Help.h"
- #import <appkit/appkit.h>
- #import <sys/dir.h> //for getdirentries()
-
- #define GENERAL_HELP_FILE LocalString("General Help.rtf")
-
- @implementation Help:Object
-
- - init
- {
- LocalHelp(helpDirectory,LocalString("Help"));
- sprintf(noHelpFile,"%s/%s",helpDirectory,GENERAL_HELP_FILE);
- return self;
- }
-
- - setHelpBrowser:anObject;
- /* Sets the helpBrowser outlet, and calls on the browser to load up.
- */
- {
- helpBrowser = anObject;
- [helpBrowser setDelegate:self];
- [helpBrowser loadColumnZero];
- return self;
- }
-
- /* TARGET/ACTION METHODS */
-
- - generalHelp:sender;
- /* This is the target/action method for the "Help" menu item. This method
- * will show the "general help" file.
- */
- {
- [self showHelpFile:GENERAL_HELP_FILE];
- return self;
- }
-
- - browserHit:sender
- /* This is the target/action method from the help topics browser. When
- * a help topic is selected, this method will show the help file for that
- * topic.
- */
- {
- [self showHelpFile:[[[sender matrixInColumn:0] selectedCell] stringValue]];
- return self;
- }
-
-
- - print:sender;
- /* This method is called by the Print menu cell in the main menu. It will
- * print the current help file.
- */
- {
- [[helpScrollView docView] printPSCode:sender];
- return self;
- }
-
- - showHelpFile:(const char *)filename;
- /* Tries to open a stream for the specified file in the Help
- * directory so the text object can readRichText. Also selects the
- * filename in the browser of help topics. If the filename doesn't exist,
- * it will select and display the "no help" file. It also brings the
- * help panel to the front.
- */
- {
- NXStream *stream;
- char helpFile[MAXPATHLEN+1];
- static NXPoint origin = {0.0,0.0};
-
- if (![self browser:helpBrowser selectCell:filename inColumn:0])
- [self browser:helpBrowser selectCell:GENERAL_HELP_FILE inColumn:0];
- sprintf(helpFile,"%s/%s",helpDirectory,filename);
- if ((stream = NXMapFile(helpFile,NX_READONLY)) == NULL)
- stream = NXMapFile(noHelpFile,NX_READONLY);
- if (stream != NULL) {
- [helpPanel disableFlushWindow];
- [[helpScrollView docView] readRichText:stream];
- [[helpScrollView docView] scrollPoint:&origin];
- [[helpPanel reenableFlushWindow] flushWindow];
- NXCloseMemory(stream,NX_FREEBUFFER);
- }
- [helpPanel orderFront:self];
- return self;
- }
-
-
- static BOOL isOk(const char *s)
- /* checks to make sure the filename is not NULL and to verify that it is
- * not a "dot"--hidden file.
- */
- {
- return (!s[0] || s[0] == '.') ? NO : YES;
- }
-
- static int caseInsensitiveCompare(void *arg1, void *arg2)
- /* Compares the two arguments without regard for case using strcasecmp().
- */
- {
- char *string1, *string2;
-
- string1 = *((char **)arg1);
- string2 = *((char **)arg2);
- return strcasecmp(string1,string2);
- }
-
- static char **fileList;
-
- - (int)browser:sender fillMatrix:matrix inColumn:(int)column
- /* This delegate method goes out to the help directory and gets a list
- * of all the files in that directory. It creates a list of file names
- * for the static variable fileList, and will load the filenames into the
- * browser on demand (lazy loading).
- */
- {
- long basep;
- char *buf;
- struct direct *dp;
- char **list = NULL;
- int cc, fd, fileCount = 0;
- char dirbuf[8192];
-
- if ((fd = open(helpDirectory, O_RDONLY, 0644)) > 0) {
- cc = getdirentries(fd, (buf = dirbuf), 8192, &basep);
- while (cc) {
- dp = (struct direct *)buf;
- if (isOk(dp->d_name)) {
- list = addFile(dp->d_name, list, fileCount++, MyZone);
- }
- buf += dp->d_reclen;
- if (buf >= dirbuf + cc) {
- cc = getdirentries(fd, (buf = dirbuf), 8192, &basep);
- }
- }
- close(fd);
- if (list) qsort(list,fileCount,sizeof(char *),caseInsensitiveCompare);
- }
- freeList(fileList);
- fileList = list;
- return fileCount;
- }
-
- - browser:sender loadCell:cell atRow:(int)row inColumn:(int)column
- /* This delegate method loads the cell for a given row. The stringValue
- * for that row comes from the fileList.
- */
- {
- if (fileList) {
- id originalFont = [cell font];
- id useFont = [Font newFont:LocalHelpFont() size:[originalFont pointSize]];
- if (useFont) {
- [cell setFont:useFont];
- [originalFont free];
- }
- [cell setStringValueNoCopy:fileList[row]];
- [cell setLeaf:YES];
- }
- return self;
- }
-
-
- - (BOOL)browser:sender selectCell:(const char *)title inColumn:(int)column
- /* This delegate method selects the cell with the given title. If it finds
- * a cell with that title, it verifies that it has a file entry in the
- * fileList, forces the loading of the cell, selects it (highlights) and
- * scrolls the browser so the cell is visible. It returns a boolean value
- * which indicates whether the cell was found.
- */
- {
- int row;
- id matrix;
-
- if (title) {
- matrix = [sender matrixInColumn:column];
- if (!fileList) return NO;
- for (row = [matrix cellCount]-1; row >= 0; row--) {
- if (fileList[row] && !strcmp(title, fileList[row])) {
- [sender getLoadedCellAtRow:row inColumn:column];
- [matrix selectCellAt:row :0];
- [matrix scrollCellToVisible:row :0];
- return YES;
- }
- }
- }
- return NO;
- }
-
-
- /* WINDOW DELEGATE METHODS */
-
- - windowWillResize:sender toSize:(NXSize *)frameSize;
- /* This method constrains the Help Panel to a reasonable minimum size
- * when the user resizes the panel.
- */
- {
- frameSize->width = MAX(frameSize->width,400.0);
- frameSize->height = MAX(frameSize->height,350.0);
- return self;
- }
-
-
- @end